#include "baidu-ai-asr.h"
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <curl/curl.h>
#include <json/json.h>
#include <fstream>
#include <memory>

BaiduAiAsr::BaiduAiAsr(const string &appKey, const string &secretKey)
{
	mAppKey    = appKey;
	mSecretKey = secretKey;
}

inline size_t onWriteData(void *buffer, size_t size, size_t nmemb, void *userp)
{
	std::string *str = dynamic_cast<std::string *>((std::string *)userp);
	str->append((char *)buffer, size * nmemb);
	return nmemb;
}

/**
 * 获取token
*/
string BaiduAiAsr::getAcessToken(void)
{
	std::string result;
	CURL *      curl;
	CURLcode    res;
	curl = curl_easy_init();
	if(curl)
	{
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		string url = "https://aip.baidubce.com/oauth/2.0/token?client_id=" + mAppKey + "&client_secret=" + mSecretKey + "&grant_type=client_credentials";
		// cout << "request url :" << url << endl;
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
		curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "undefined");
		struct curl_slist *headers = NULL;
		headers                    = curl_slist_append(headers, "Content-Type: application/json");
		headers                    = curl_slist_append(headers, "Accept: application/json");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		const char *data = "";
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
		res = curl_easy_perform(curl);
		curl_slist_free_all(headers);
	}
	curl_easy_cleanup(curl);
	return parseJson(result, "access_token");
}

string BaiduAiAsr::parseJson(const string &jsonData, const string &key)
{
	Json::Reader reader;
	Json::Value  root;
	bool         ok = reader.parse(jsonData, root);
	if(!ok)
	{
		return string();
	}
	return root[key].asString();
}

string BaiduAiAsr::parseJonsToAudioText(const string &jsonData)
{
	Json::Reader reader;
	Json::Value  root;
	bool         ok = reader.parse(jsonData, root);
	if(!ok)
	{
		return string();
	}
	cout << jsonData << endl;
	return root["result"][0].asString();
}

/**
 * 音频转文字
*/
string BaiduAiAsr::asrAudioData(const string &token, const vector<uint8_t> &audio)
{
	std::string result;
	CURL *      curl;
	CURLcode    res;
	curl = curl_easy_init();
	if(curl)
	{
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		string url = "http://vop.baidu.com/server_api?dev_pid=1537&cuid=1234567C&token=" + token;
		// cout << "request url :" << url << endl;
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
		curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
		struct curl_slist *headers = NULL;
		headers                    = curl_slist_append(headers, "Content-Type: audio/pcm;rate=16000");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		const char *data = "";
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audio.data());
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, audio.size()); // 音频数据长度
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
		res = curl_easy_perform(curl);
		curl_slist_free_all(headers);
	}
	curl_easy_cleanup(curl);

	if(res != CURLE_OK)
	{
		// curl 失败
		fprintf(stderr, "perform curl error: %s.\n", curl_easy_strerror(res));
		return string();
	}
	// cout << result << endl;
	return parseJonsToAudioText(result);
}
